package com.mvity.framework.common.utils;

import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;

import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;

import com.mvity.framework.common.base.BaseUtil;
import com.mvity.framework.common.global.Constants;

/**
 * 加密工具类
 * 
 * @author vity
 * @date 2012-7-13
 * @mail vity.1215@gmail.com
 */
public final class CryptoUtil extends BaseUtil {

	private static final long serialVersionUID = 8621160742892094865L;
	private static Key DES_KEY;
	private static String DES_KEY_STR = "vity";
	private static Base64 base64 = new Base64();

	static {
		try {
			KeyGenerator generator = KeyGenerator.getInstance("DES");
			generator.init(new SecureRandom(DES_KEY_STR.getBytes()));
			DES_KEY = generator.generateKey();
			generator = null;

		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	/**
	 * 用 BASE64 算法加密字符串
	 * 
	 * @param value
	 * @return
	 * @throws UnsupportedEncodingException
	 */
	public static String encryptBASE64String(String value) throws UnsupportedEncodingException {
		return base64.encodeAsString(value.getBytes(Constants.DEFAULT_CHARSET));
	}

	/**
	 * 用 BASE64 算法解密字符串
	 * 
	 * @param value
	 * @return
	 * @throws UnsupportedEncodingException
	 */
	public static String decryptBASE64String(String value) throws UnsupportedEncodingException {
		return StringUtils.toString(base64.decode(value), Constants.DEFAULT_CHARSET);
	}

	/**
	 * 用 DES算法加密字符串
	 * 
	 * @param value
	 * @return
	 * @throws InvalidKeyException
	 * @throws UnsupportedEncodingException
	 * @throws NoSuchPaddingException
	 * @throws NoSuchAlgorithmException
	 * @throws BadPaddingException
	 * @throws IllegalBlockSizeException
	 */
	public static String encryptDESString(String value) throws InvalidKeyException, UnsupportedEncodingException, NoSuchAlgorithmException,
			NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException {
		byte[] strBytes = value.getBytes(Constants.DEFAULT_CHARSET);
		Cipher cipher = Cipher.getInstance("DES");
		cipher.init(Cipher.ENCRYPT_MODE, DES_KEY);
		byte[] encryptStrBytes = cipher.doFinal(strBytes);
		return base64.encodeAsString(encryptStrBytes);
	}

	/**
	 * 用 DES 算法解密字符串
	 * 
	 * @param value
	 * @return
	 * @throws NoSuchPaddingException
	 * @throws NoSuchAlgorithmException
	 * @throws BadPaddingException
	 * @throws IllegalBlockSizeException
	 * @throws InvalidKeyException
	 * @throws UnsupportedEncodingException
	 */
	public static String decryptDESString(String value) throws NoSuchAlgorithmException, NoSuchPaddingException, IllegalBlockSizeException,
			BadPaddingException, InvalidKeyException, UnsupportedEncodingException {
		byte[] strBytes = base64.decode(value);
		Cipher cipher = Cipher.getInstance("DES");
		cipher.init(Cipher.DECRYPT_MODE, DES_KEY);
		byte[] decryptStrBytes = cipher.doFinal(strBytes);
		return StringUtils.toString(decryptStrBytes, Constants.DEFAULT_CHARSET);
	}

	/**
	 * 用 HEX 算法加密字符串
	 * 
	 * @param value
	 * @return
	 * @throws UnsupportedEncodingException
	 */
	public static String encryptHexString(String value) throws UnsupportedEncodingException {
		return Hex.encodeHexString(value.getBytes(Constants.DEFAULT_CHARSET));
	}

	/**
	 * 用 HEX 算法解密字符串
	 * 
	 * @param value
	 * @return
	 * @throws DecoderException
	 * @throws UnsupportedEncodingException
	 */
	public static String decryptHexString(String value) throws UnsupportedEncodingException, DecoderException {
		System.out.println(StringUtils.toString(Hex.decodeHex((value.toCharArray())), Constants.DEFAULT_CHARSET));
		return "";
	}

	/**
	 * 用 MD5 算法加密字符串
	 * 
	 * @param value
	 * @return
	 */
	public static String encryptMD5String(String value) {
		return DigestUtils.md5Hex(value);
	}

	/**
	 * 用 SHA 算法加密字符串
	 * 
	 * @param value
	 * @param bit
	 *            1/256/384/512
	 * @return
	 */
	public static String encryptSHAString(String value, int bit) {
		switch (bit) {
		case 512:
			return DigestUtils.sha512Hex(value);
		case 384:
			return DigestUtils.sha384Hex(value);
		case 256:
			return DigestUtils.sha256Hex(value);
		default:
			return DigestUtils.shaHex(value);
		}
	}

	/**
	 * 用 SHA-1 算法 加密字符串
	 * 
	 * @param value
	 * @return
	 */
	public static String encryptSHAString(String value) {
		return encryptSHAString(value, 0);
	}

	public static void main(String[] args) throws Exception {

		System.out.println(CryptoUtil.encryptDESString("gms"));

		String s = CryptoUtil.encryptBASE64String("傻帽");
		System.out.println(s);
		System.out.println(CryptoUtil.decryptBASE64String(s));

		String ss = CryptoUtil.encryptHexString("chin啊是灯笼裤飞机aslkdjflkajsdf");
		System.out.println(ss);
		System.out.println(CryptoUtil.decryptHexString(ss));
		System.out.println("cfcd208495d565ef66e7dff9f98764da".equals(CryptoUtil.encryptMD5String("0")));
		String n = "啊啦可适当降分asdlf4564@4654asdf23";
		System.out.println(CryptoUtil.encryptSHAString(n));
		System.out.println(CryptoUtil.encryptSHAString(n, 256));
		System.out.println(CryptoUtil.encryptSHAString(n, 384));
		System.out.println(CryptoUtil.encryptSHAString(n, 512));
	}

}
